﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Configuration;
using System.Collections.Specialized;
using System.Xml;
using System.IO;
using Microsoft.Web.Administration;
using System.Configuration.Install;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.ServiceProcess;

namespace TicketingServerSetup
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        string AppRoot; 
        private void Form1_Load(object sender, EventArgs e)
        {
            cmbExVer.SelectedIndex = 0;
        }

        private void button1_Click(object sender, EventArgs e)
        {

            
                //Copy the contents to target directory on TFS
                AppRoot = Path.GetPathRoot(System.Environment.SystemDirectory) + "Program Files\\SSGS\\TicketManager";
                //AppRoot = "C:\\Program Files\\SSGS\\TicketManager";
                string parentDir = System.Environment.SystemDirectory + "Program Files\\SSGS";
                //string parentDir = "C:\\Program Files\\SSGS";
                if (Directory.Exists(parentDir))
                {
                    Directory.Delete(parentDir, true);
                }
                CopyFolder(Directory.GetCurrentDirectory(), AppRoot);
                Logger.CreateLogEntry("TicketM Installation: SSGS folder created ");
                try
                {
                    //write data to config file
                    XmlDocument doc = new XmlDocument();
                    doc.Load(AppRoot + "/TicketM/Configuration/TicketProcessingService.exe.config");
                    XmlNode root = doc.DocumentElement;
                    root.SelectSingleNode("/configuration/appSettings/add[@key='Tfs']").Attributes["value"].Value = txtTfs.Text;
                    root.SelectSingleNode("/configuration/appSettings/add[@key='Collection']").Attributes["value"].Value = txtCollection.Text;
                    root.SelectSingleNode("/configuration/appSettings/add[@key='Project']").Attributes["value"].Value = txtProject.Text;
                    root.SelectSingleNode("/configuration/appSettings/add[@key='UserName']").Attributes["value"].Value = txtUserName.Text;
                    root.SelectSingleNode("/configuration/appSettings/add[@key='Password']").Attributes["value"].Value = txtPassword.Text;
                    root.SelectSingleNode("/configuration/appSettings/add[@key='Domain']").Attributes["value"].Value = txtDomain.Text;
                    root.SelectSingleNode("/configuration/appSettings/add[@key='ExchServerName']").Attributes["value"].Value = txtExchServerName.Text;
                    root.SelectSingleNode("/configuration/appSettings/add[@key='ExVer']").Attributes["value"].Value = cmbExVer.SelectedText;
                    root.SelectSingleNode("/configuration/appSettings/add[@key='HelpDeskUser']").Attributes["value"].Value = txtHelpDeskUser.Text;
                    root.SelectSingleNode("/configuration/appSettings/add[@key='HelpDeskPassword']").Attributes["value"].Value = txtHelpDeskPassword.Text;
                    root.SelectSingleNode("/configuration/appSettings/add[@key='ReportServerName']").Attributes["value"].Value = txtReportServerName.Text;
                    //root.SelectSingleNode("/configuration/appSettings/add[@key='Periodicity']").Attributes["value"].Value = Periodicity.Text;
                    doc.Save(AppRoot + "/TicketM/Configuration/TicketProcessingService.exe.config");
                    Logger.CreateLogEntry("TicketM Installation: Config file written");
                }
                catch (Exception ex)
                {
                    Logger.CreateLogEntry("!!!ERROR While creating config file during installation. Reverting Installation. Exception: " + ex.Message);
                    Directory.Delete(AppRoot);
                }
                
                if (CreateTeamProject(txtProject.Text, "http://" + txtTfs.Text + ":8080/tfs/" + txtCollection.Text))
                {
                    //create site
                    using (ServerManager serverManager = new ServerManager())
                    {
                        //create app pool  
                        bool exists = false;
                        ApplicationPool newAppPool = null;
                        string appPoolName = "TicketPool";
                        foreach (ApplicationPool a in serverManager.ApplicationPools)
                        {
                            if (a.Name == appPoolName)
                            {
                                Logger.CreateLogEntry("**INFO App pool exists");
                                exists = true;
                                break;
                            }
                            else
                            {
                                exists = false;
                            }
                        }

                        if (!exists)
                        {
                            newAppPool = serverManager.ApplicationPools.Add(appPoolName);
                            newAppPool.ManagedRuntimeVersion = "v4.0";
                            newAppPool.ProcessModel.IdentityType = ProcessModelIdentityType.SpecificUser;
                            newAppPool.ProcessModel.UserName = txtDomain.Text + "\\" + txtUserName.Text;
                            newAppPool.ProcessModel.Password = txtPassword.Text;
                            newAppPool.Enable32BitAppOnWin64 = true;
                            try
                            {
                                serverManager.CommitChanges();
                                Logger.CreateLogEntry("TicketM Installation: App Pool Created");
                            }
                            catch (Exception ex)
                            {
                                Logger.CreateLogEntry("!!!ERROR While creating App Pool. Reverting Installation. Exception: " + ex.Message);
                                Directory.Delete(AppRoot, true);
                            }
                            
                        }
                        // find if the site already exists
                        foreach (Site s in serverManager.Sites)
                        {
                            if (s.Name == "TicketManager")
                            {
                                Logger.CreateLogEntry("**INFO Site already exists");
                                exists = true;
                                break;
                            }
                            else
                            {
                                exists = false;
                            }

                        }
                        if (!exists)
                        {
                            string sitePath = AppRoot;
                            serverManager.Sites.Add("TicketManager", "http", "*:9090:", sitePath);
                            serverManager.CommitChanges();
                            Site site = serverManager.Sites["TicketManager"];
                            string AppPath = sitePath + "\\TicketM\\";
                            Microsoft.Web.Administration.Application app = site.Applications.Add("/TicketM", AppPath);
                            app.ApplicationPoolName = "TicketPool";
                            try
                            {
                                serverManager.CommitChanges();
                                Logger.CreateLogEntry("TicketM Installation: TicketM Site created");
                            }
                            catch (Exception ex)
                            {
                                ApplicationPool appPool = serverManager.ApplicationPools["TicketPool"];
                                serverManager.ApplicationPools.Remove(appPool);
                                serverManager.CommitChanges();
                                Logger.CreateLogEntry("!!!ERROR While creating Site. Reverting Installation. Exception: " + ex.Message);
                                Directory.Delete(AppRoot, true);
                            }
                        }

                    }
                    //install windows service
                    try
                    {
                        string path = AppRoot + @"\TicketM\Configuration\TicketProcessingService.exe";
                        FileUnblocker fileunblock = new FileUnblocker();
                        fileunblock.Unblock(path);                    
                        ManagedInstallerClass.InstallHelper(new string[] { path });
                        ServiceController service = new ServiceController("TicketProcessingService");
                        service.Start();
                        Logger.CreateLogEntry("TicketM Installation: Ticket Processing Service created and started");
                    }
                    catch (Exception ex)
                    {
                        ServerManager serverManager = new ServerManager();
                        Site site = serverManager.Sites["TicketManager"];
                        serverManager.Sites.Remove(site);
                        serverManager.CommitChanges(); ApplicationPool appPool = serverManager.ApplicationPools["TicketPool"];
                        serverManager.ApplicationPools.Remove(appPool);
                        serverManager.CommitChanges();
                        Logger.CreateLogEntry("!!!ERROR While creating Ticket Processor Service. Reverting Installation. Exception: " + ex.Message);
                        Directory.Delete(AppRoot, true);
                    }
                    //Coopy event handler files
                    string src1 = AppRoot + @"\CustomEventHandler.dll";
                    //string src2 = AppRoot + @"\CustomEventHandler.dll.config";
                    string dst1 = Path.GetPathRoot(System.Environment.SystemDirectory) + @"\Program Files\Microsoft Team Foundation Server 12.0\Application Tier\Web Services\bin\Plugins\CustomEventHandler.dll.dll";
                    //string dst2 = Path.GetPathRoot(System.Environment.SystemDirectory) + @"\Program Files\Microsoft Team Foundation Server 12.0\Application Tier\Web Services\bin\Plugins\CustomEventHandler.dll.config";

                    try
                    {
                        File.Copy(src1, dst1, true);
                        //File.Copy(src2, dst2, true);
                    }
                    catch (Exception ex)
                    {
                        //stop service
                        ServiceController service = new ServiceController("TicketProcessingService");
                        service.Stop();
                        Logger.CreateLogEntry("TicketM Installation ERROR: Service stopped");
                        // unistall Windows Service
                        string servicePath = AppRoot + @"\TicketM\Configuration\TicketProcessingService.exe";
                        ManagedInstallerClass.InstallHelper(new string[] { "/u", servicePath });
                        ServerManager serverManager = new ServerManager();
                        Site site = serverManager.Sites["TicketManager"];
                        serverManager.Sites.Remove(site);
                        serverManager.CommitChanges(); ApplicationPool appPool = serverManager.ApplicationPools["TicketPool"];
                        serverManager.ApplicationPools.Remove(appPool);
                        serverManager.CommitChanges();
                        Logger.CreateLogEntry("!!!ERROR While copying notification engine. Reverting Installation. Exception: " + ex.Message);
                        Directory.Delete(AppRoot, true);
                    }
                    Logger.CreateLogEntry("TicketM Installation: Event handler files copied");
                    MessageBox.Show("TicketM Application Successfully Launched", "TicketM", MessageBoxButtons.OK, MessageBoxIcon.Information);

                    button3.Enabled = true;
                    button1.Enabled = false;
                }
                else
                {
                    MessageBox.Show("Setup Failed. All Earlier actions reverted.");
                }
        }
        static public void CopyFolder(string sourceFolder, string destFolder)
        {
            if (!Directory.Exists(destFolder))
                Directory.CreateDirectory(destFolder);
            string[] files = Directory.GetFiles(sourceFolder);
            foreach (string file in files)
            {
                string name = Path.GetFileName(file);
                string dest = Path.Combine(destFolder, name);
                File.Copy(file, dest);
            }
            string[] folders = Directory.GetDirectories(sourceFolder);
            foreach (string folder in folders)
            {
                string name = Path.GetFileName(folder);
                string dest = Path.Combine(destFolder, name);
                CopyFolder(folder, dest);
            }
        }
        private bool CreateTeamProject(string ProjectName, string Collection)
        {
            bool ProjectCreated = false;
            try
            {
                string tfpt = Path.GetPathRoot(System.Environment.SystemDirectory) +   @"Program Files (x86)\Microsoft Team Foundation Server 2013 Power Tools\tfpt.exe" ;
                string args = " createteamproject /collection:\"" + Collection + "\" /teamproject:\"" + ProjectName + "\" /processtemplate:\"MSF for CMMI Process Improvement 2013\" /sourcecontrol:None /noreports /noportal";
                Logger.CreateLogEntry("**INFO TFPT " + tfpt);
                Logger.CreateLogEntry("**INFO Remanining args " + args);
                MessageBox.Show("We are now creating a team project named " + ProjectName + ". This will take a few minutes. Please do not close the command window. It will close itself once the team project is created", "Creating Team Project", MessageBoxButtons.OK, MessageBoxIcon.Information);
                //start the process
                Process p = Process.Start(tfpt,args);
                
                //p.StandardInput.WriteLine(args);
                p.WaitForExit();
                
               // p.StandardInput.WriteLine("EXIT");
                p.Close();
                Logger.CreateLogEntry("Team Project Created" + txtProject.Text);
                ProjectCreated = true;
            }
            catch (Exception ex)
            {
                string logEntry = ex.Message;
                if (ex.InnerException != null)
                {
                    logEntry += " " + ex.InnerException.Message;
                }
                Logger.CreateLogEntry("!!!ERROR While creating Team Project. Reverting Installation. Exception: " + ex.Message);
                Directory.Delete(AppRoot, true);
            }
            return ProjectCreated;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.Application.Exit();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.Application.Exit();
        }

        private void txtUserName_Enter(object sender, EventArgs e)
        {
            toolTip1.SetToolTip(label4, "Please provide only the user name");
        }

        

    }
    public class FileUnblocker
    {
        [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool DeleteFile(string name);

        public bool Unblock(string fileName)
        {
            return DeleteFile(fileName + ":Zone.Identifier");
        }
    }
}
